repo: Don't require a txn for writing
authorColin Walters <walters@verbum.org>
Mon, 26 May 2014 22:32:17 +0000 (18:32 -0400)
committerColin Walters <walters@verbum.org>
Mon, 26 May 2014 22:49:17 +0000 (18:49 -0400)
The current "transaction" symlink was introduced to fix issues with
interrupted pulls; normally we assume that if we have a metadata
object, we also have all objects to which it refers.

There used to be a "summary" which had all the available refs, but I
deleted it because it wasn't really used, and was still racy despite
the transaction bits.

We still want the pull process to use the transaction link, so don't
delete the APIs, just relax the restriction on object writing, and
introduce a new ostree_repo_set_ref_immediate().

src/libostree/ostree-repo-commit.c
src/libostree/ostree-repo-private.h
src/libostree/ostree-repo-refs.c
src/libostree/ostree-repo.h
src/ostree/ot-builtin-refs.c

index 398f6abdd457cbe4a9851a0ab649a4f905f5be94..c3bc8368c7b651675f0e22774343e9153e7ce8a2 100644 (file)
@@ -368,8 +368,6 @@ write_object (OstreeRepo         *self,
   gsize unpacked_size = 0;
   gboolean indexable = FALSE;
 
-  g_return_val_if_fail (self->in_transaction, FALSE);
-  
   if (g_cancellable_set_error_if_cancelled (cancellable, error))
     return FALSE;
 
@@ -930,6 +928,31 @@ ostree_repo_transaction_set_ref (OstreeRepo *self,
   g_hash_table_replace (self->txn_refs, refspec, g_strdup (checksum));
 }
 
+/**
+ * ostree_repo_set_ref_immediate:
+ * @self: An #OstreeRepo
+ * @remote: (allow-none): A remote for the ref
+ * @ref: The ref to write
+ * @checksum: The checksum to point it to
+ * @cancellable: GCancellable
+ * @error: GError
+ *
+ * This is like ostree_repo_transaction_set_ref(), except it may be
+ * invoked outside of a transaction.  This is presently safe for the
+ * case where we're creating or overwriting an existing ref.
+ */
+gboolean
+ostree_repo_set_ref_immediate (OstreeRepo *self,
+                               const char *remote,
+                               const char *ref,
+                               const char *checksum,
+                               GCancellable  *cancellable,
+                               GError       **error)
+{
+  return _ostree_repo_write_ref (self, remote, ref, checksum,
+                                 cancellable, error);
+}
+
 /**
  * ostree_repo_commit_transaction:
  * @self: An #OstreeRepo
index b12e116a756612a8a695a4eccddcf3b60a4712db..379460ab62d855dadd74109c7429880c825c8d4b 100644 (file)
@@ -122,6 +122,14 @@ _ostree_repo_update_refs (OstreeRepo        *self,
                           GCancellable      *cancellable,
                           GError           **error);
 
+gboolean      
+_ostree_repo_write_ref (OstreeRepo    *self,
+                        const char    *remote,
+                        const char    *ref,
+                        const char    *rev,
+                        GCancellable  *cancellable,
+                        GError       **error);
+
 OstreeRepoFile *
 _ostree_repo_file_new_for_commit (OstreeRepo  *repo,
                                   const char  *commit,
index ba3bedb72b554541c600c21172110b15fa6f404f..64ae96f7c8b6e847630a1aab6a5460877ad56307 100644 (file)
@@ -570,21 +570,17 @@ ostree_repo_list_refs (OstreeRepo       *self,
   return ret;
 }
 
-static gboolean      
-write_refspec (OstreeRepo    *self,
-               const char    *refspec,
-               const char    *rev,
-               GCancellable  *cancellable,
-               GError       **error)
+gboolean      
+_ostree_repo_write_ref (OstreeRepo    *self,
+                        const char    *remote,
+                        const char    *ref,
+                        const char    *rev,
+                        GCancellable  *cancellable,
+                        GError       **error)
 {
   gboolean ret = FALSE;
-  gs_free char *remote = NULL;
-  gs_free char *name = NULL;
   gs_unref_object GFile *dir = NULL;
 
-  if (!ostree_parse_refspec (refspec, &remote, &name, error))
-    goto out;
-
   if (remote == NULL)
     dir = g_object_ref (self->local_heads_dir);
   else
@@ -600,7 +596,7 @@ write_refspec (OstreeRepo    *self,
 
   if (rev == NULL)
     {
-      gs_unref_object GFile *child = g_file_resolve_relative_path (dir, name);
+      gs_unref_object GFile *child = g_file_resolve_relative_path (dir, ref);
 
       if (g_file_query_exists (child, cancellable))
         {
@@ -610,7 +606,7 @@ write_refspec (OstreeRepo    *self,
     }
   else
     {
-      if (!write_checksum_file (dir, name, rev, cancellable, error))
+      if (!write_checksum_file (dir, ref, rev, cancellable, error))
         goto out;
     }
 
@@ -634,8 +630,14 @@ _ostree_repo_update_refs (OstreeRepo        *self,
     {
       const char *refspec = key;
       const char *rev = value;
+      gs_free char *remote = NULL;
+      gs_free char *ref = NULL;
+
+      if (!ostree_parse_refspec (refspec, &remote, &ref, error))
+        goto out;
 
-      if (!write_refspec (self, refspec, rev, cancellable, error))
+      if (!_ostree_repo_write_ref (self, remote, ref, rev,
+                                   cancellable, error))
         goto out;
     }
 
index 0ff114b3301fd05baeb7a06e90b8cdea96a184a5..562e6c1867a6e671472242fab38e2289849bd18b 100644 (file)
@@ -133,6 +133,13 @@ void          ostree_repo_transaction_set_ref     (OstreeRepo *self,
                                                    const char *ref,
                                                    const char *checksum);
 
+gboolean      ostree_repo_set_ref_immediate (OstreeRepo *self,
+                                             const char *remote,
+                                             const char *ref,
+                                             const char *checksum,
+                                             GCancellable  *cancellable,
+                                             GError       **error);
+
 gboolean      ostree_repo_has_object (OstreeRepo           *self,
                                       OstreeObjectType      objtype,
                                       const char           *checksum,
index 3fbe571f7c4241118db448c443583018dc0656fc..9c291fbab580bf0785a441f80773c6fd891f88de 100644 (file)
@@ -67,18 +67,20 @@ ostree_builtin_refs (int argc, char **argv, OstreeRepo *repo, GCancellable *canc
     }
   else
     {
-      if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
-        goto out;
-
       g_hash_table_iter_init (&hashiter, refs);
       while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
         {
           const char *refspec = hashkey;
-          ostree_repo_transaction_set_refspec (repo, refspec, NULL);
-        }
+          gs_free char *remote = NULL;
+          gs_free char *ref = NULL;
 
-      if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
-        goto out;
+          if (!ostree_parse_refspec (refspec, &remote, &ref, error))
+            goto out;
+          
+          if (!ostree_repo_set_ref_immediate (repo, remote, ref, NULL,
+                                              cancellable, error))
+            goto out;
+        }
     }
 
   ret = TRUE;